@tool
class_name Detector_Target
extends Detector

#region 属性
@export var radius:float = 30
@export var target_type:GameEnum.TargetDetectorTargetType
@export_flags_2d_physics var obstacle_layer_mask:int
var ray_cast_2d:RayCast2D
var targets:Array[Node2D]
#endregion
#region 字段
#endregion
#region 信号
#endregion

#region 基类方法
func init(entity:Entity,args:Dictionary = {}) -> bool:
	if super.init(entity):
		ray_cast_2d = RayCast2D.new()
		ray_cast_2d.enabled = false
		add_child(ray_cast_2d)
		return true
	return false
func set_enable(enable:bool):
	if enable and not self.enable:
		if ray_cast_2d:
			ray_cast_2d.target_position = Vector2(radius,0)
			ray_cast_2d.enabled = true
	elif not enable and self.enable:
		if ray_cast_2d:
			ray_cast_2d.enabled = false
func update(delta:float) -> bool:
	if super(delta):
		#ray_cast_2d.collision_mask = entity.entity_data.get_obstacle_layer_mask()
		ray_cast_2d.collision_mask = obstacle_layer_mask
		targets = GameCampSystem.get_target(GameCampSystem.get_target_camps(entity.entity_data.get_attribute_value("Camp")),global_position,true,-1,radius)
		# 记录StateManager需要的参数
		var state_component:StateComponent = entity.get_component(StateComponent)
		if state_component:
			var state_chart:StateChart = state_component.get_state_chart_manager().chart
			if state_chart:
				var property_name = "TargetAmount"
				state_chart.set_expression_property(property_name,targets.size())
		return true
	return false
func destroy():
	super()
#endregion
#region 公共方法
func get_targets(pos:Vector2,radius:float = 0,filter_func:Callable = Callable(),count:int = -1) -> Array[Node2D]:
	if radius <= 0:
		return get_normal_targets(pos,filter_func,count)
	var new_targets = GameCampSystem.get_target(GameCampSystem.get_target_camps(entity.entity_data.get_attribute_value("Camp")),global_position,true,-1,radius)
	match target_type:
		GameEnum.TargetDetectorTargetType.Target:
			var targets_copy = new_targets.duplicate()
			if filter_func and filter_func.is_valid():
				targets_copy = targets_copy.filter(filter_func)
			targets_copy.sort_custom(func (a:Vector2,b:Vector2):return (a-pos).length() < (b-pos).length())
			return targets_copy.slice(0,count if count >= 0 else targets_copy.size())
		GameEnum.TargetDetectorTargetType.VisibleTarget:
			var targets_copy = new_targets.duplicate()
			targets_copy = targets_copy.filter(func(target):
				ray_cast_2d.target_position = target.global_position - global_position
				ray_cast_2d.force_raycast_update()
				return not ray_cast_2d.is_colliding() and (filter_func.call(target) if filter_func and filter_func.is_valid() else true)
				)
			targets_copy.sort_custom(func (a:Vector2,b:Vector2):
				return (a-pos).length() < (b-pos).length()
			)
			return targets_copy.slice(0,count if count >= 0 else targets_copy.size())
		GameEnum.TargetDetectorTargetType.SameCampTarget:
			var targets_same_camp = GameCampSystem.get_target([entity.entity_data.get_attribute_value("Camp")],global_position,true,-1,radius)
			if filter_func and filter_func.is_valid():
				targets_same_camp = targets_same_camp.filter(filter_func)
			targets_same_camp.sort_custom(func (a:Vector2,b:Vector2):return (a-pos).length() < (b-pos).length())
			return targets_same_camp.slice(0,count if count >= 0 else targets_same_camp.size())
		_:
			return []
func get_normal_targets(pos:Vector2,filter_func:Callable = Callable(),count:int = -1) -> Array[Node2D]:
	match target_type:
		GameEnum.TargetDetectorTargetType.Target:
			var targets_copy = targets.duplicate()
			if filter_func and filter_func.is_valid():
				targets_copy = targets_copy.filter(filter_func)
			targets_copy.sort_custom(func (a:Vector2,b:Vector2):return (a-pos).length() < (b-pos).length())
			return targets_copy.slice(0,count if count >= 0 else targets_copy.size())
		GameEnum.TargetDetectorTargetType.VisibleTarget:
			var targets_copy = targets.duplicate()
			targets_copy = targets_copy.filter(func(target):
				ray_cast_2d.target_position = target.global_position - global_position
				ray_cast_2d.force_raycast_update()
				return not ray_cast_2d.is_colliding() and (filter_func.call(target) if filter_func and filter_func.is_valid() else true)
				)
			targets_copy.sort_custom(func (a:Vector2,b:Vector2):
				return (a-pos).length() < (b-pos).length()
			)
			return targets_copy.slice(0,count if count >= 0 else targets_copy.size())
		GameEnum.TargetDetectorTargetType.SameCampTarget:
			var targets_same_camp = GameCampSystem.get_target([entity.entity_data.get_attribute_value("Camp")],global_position,true,-1,radius)
			if filter_func and filter_func.is_valid():
				targets_same_camp = targets_same_camp.filter(filter_func)
			targets_same_camp.sort_custom(func (a:Vector2,b:Vector2):return (a-pos).length() < (b-pos).length())
			return targets_same_camp.slice(0,count if count >= 0 else targets_same_camp.size())
		_:
			return []
#endregion
#region 私有方法
#endregion
#region 生命周期函数
func _init() -> void:
	detector_type = GameEnum.DetectorType.Target
func _draw() -> void:
	if not is_debug:
		return
	if GameManager.game_mode != GameEnum.GameMode.Dev:
		return
	draw_circle(position,radius,Color.GREEN,false)
#endregion
